home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XA_6S.ZIP / SOURCE / KERNAL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-15  |  10.5 KB  |  350 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <OSBIND.H>
  9. #include <FILESYS.H>
  10. #include <MINTBIND.H>
  11.  
  12. #ifdef __PUREC__
  13. #include <sys\types.h>
  14. #else
  15. #include <sys/types.h>
  16. #endif
  17.  
  18. #include <memory.h>
  19. #include "K_DEFS.H"
  20. #include "KERNAL.H"
  21. #include "XA_GLOBL.H"
  22. #include "XA_CODES.H"
  23. #include "XA_DEFS.H"
  24. #include "APP_MAN.H"
  25. #include "APPL_INI.H"
  26. #include "APPL_WRT.H"
  27. #include "APPLSEAR.H"
  28. #include "NEW_CLNT.H"
  29. #include "GETINFO.H"
  30. #include "EVNT_BTN.H"
  31. #include "EVNT_KBD.H"
  32. #include "EVNT_MES.H"
  33. #include "EVNT_MUL.H"
  34. #include "EVNT_TMR.H"
  35. #include "MOUSE_CL.H"
  36. #include "WIND_FNS.H"
  37. #include "GRAF_MOU.H"
  38. #include "GRAF_BOX.H"
  39. #include "GRAFGROW.H"
  40. #include "KEYBOARD.H"
  41. #include "RESOURCE.H"
  42. #include "OBJC_DRW.H"
  43. #include "OBJCEDIT.H"
  44. #include "FORMS.H"
  45. #include "FRM_ALRT.H"
  46. #include "MENUBAR.H"
  47. #include "SHELL.H"
  48. #include "EXTEND.H"
  49. #include "SCRAP.H"
  50. #include "op_names.h"
  51. #include "FSEL_INP.H"
  52.  
  53. far AESroutine Ktable[300];        /* The main AES kernal command jump table */
  54. far short Kcall_direct[300];    /* array of flags to indicate that routines should be direct called */
  55. far XA_CLIENT clients[MAX_PID+1];    /* The clients database */
  56.  
  57. short shutdown=FALSE;            /* When this gets set to true, the system will exit */
  58.  
  59. /*
  60.     Kernal Message Handler
  61.  
  62.     This is responsible for accepting requests via the XaAES.cmd pipe and
  63.     sending (most) replies via the client's reply pipe.
  64.     
  65.     We also get keyboard & mouse input data here.
  66. */
  67. extern unsigned long client_handle_mask;
  68.  
  69. void kernal(void)
  70. {
  71.     unsigned short cmd,packet_type;
  72.     unsigned long rtn=XA_OK;
  73.     short client_handle;
  74.     AESPB *parms;
  75.     MOOSE_BUTTON_DATA mdata;
  76.     AESroutine cmd_routine;
  77.     short clnt_pid;
  78.     unsigned long repl;
  79.     unsigned long input_channels;
  80.     short fs_rtn,r,evnt_count=0;
  81.  
  82. /* Unlock the semaphores....we're ready to go */
  83.     Psemaphore(3,APPL_INIT_SEMAPHORE,0);
  84.     Psemaphore(3,TRAP_HANDLER_SEMAPHORE,0);
  85.     Psemaphore(3,WIN_LIST_SEMAPHORE,0);
  86.     Psemaphore(3,ROOT_SEMAPHORE,0);
  87.     Psemaphore(3,CLIENTS_SEMAPHORE,0);
  88.     Psemaphore(3,UPDATE_LOCK,0);
  89.     Psemaphore(3,MOUSE_LOCK,0);
  90.     Psemaphore(3,FSELECT_SEMAPHORE,0);
  91.  
  92.     DIAGS(("kernal: MOUSE_dev=%d\n",MOUSE_dev));
  93.  
  94. /* Main kernal loop */
  95.     do {
  96.         input_channels=1L<<MOUSE_dev;
  97.         input_channels|=1L<<KBD_device;                    /* We are waiting on all these channels */
  98.         input_channels|=1L<<AES_in_pipe;                /* This is only used for appl_init() now */
  99.         input_channels|=client_handle_mask;                /* Clients send general requests via their own pipes now */
  100.  
  101.         fs_rtn=Fselect(0L,(long *)&input_channels,0L,0L);    /* Block via select() on the console & the */
  102. #if 0
  103.         fs_rtn=Fselect(3000,(long *)&input_channels,NULL,NULL);    /* Block via select() on the console & the */
  104.                                                                 /* AES command pipe(s). */
  105. #endif
  106.  
  107.         if ((!fs_rtn)||(evnt_count==5000))    /* Timeout - do some housekeeping */
  108.         {
  109.             
  110.             evnt_count=0;
  111.             find_dead_clients();
  112.         
  113.         }else{
  114.             
  115.             evnt_count++;
  116.             
  117.             if (input_channels&(1L<<KBD_device))        /* Did we get some keyboard input? */
  118.             {
  119.                 do_keyboard();
  120.             }
  121.         
  122.             if (input_channels&(1L<<MOUSE_dev))            /* Did we get a mouse message? */
  123.             {
  124.                 DIAGS(("MOUSE CHANNEL ACTIVE\n"));
  125.             
  126.                 if (Fread(MOUSE_dev, (long)sizeof(unsigned short), &packet_type)!=0)    /* get Mouse data packet type*/
  127.                 {
  128.                     switch(packet_type)
  129.                     {
  130.                         case MOOSE_BUTTON_PREFIX:
  131.                             Fread(MOUSE_dev, (long)sizeof(MOOSE_BUTTON_DATA), &mdata);    /* get Mouse data packet */
  132.                             XA_button_event(&mdata);                                /* Call the mouse event handler */
  133.                             break;
  134.                         default:
  135.                             break;
  136.                     }
  137.                 }
  138.             }
  139.         
  140.             input_channels&=(client_handle_mask|(1L<<AES_in_pipe));
  141.             client_handle=0;
  142.             
  143.             while(input_channels)
  144.             {
  145.                 do {
  146.                     input_channels=input_channels>>1;
  147.                     client_handle++;
  148.                 } while((!(input_channels&1L))&&(client_handle<32));
  149.                 
  150.                 r=Fread(client_handle, (long)sizeof(short), &clnt_pid);    /* pid of the client sending the command */
  151.  
  152. /* Quick check here to get round a bug in MiNT's Fselect when used with pipes (sometimes a pipe may be reported
  153.    as having data ready for reading, when in-fact it hasn't). */
  154.                 if (r==sizeof(short))
  155.                 {
  156.                     Fread(client_handle, (long)sizeof(unsigned short),  &cmd);    /* command type */
  157.  
  158.                     Fread(client_handle, (long)sizeof(AESPB*),  &parms);    /* get a pointer to AES parameter block */
  159.  
  160. #if GENERATE_DIAGS
  161.                     if (parms->contrl[0]<=MAX_NAMED_DIAG)
  162.                     {
  163.                         if (parms->contrl[0]!=XA_EVNT_MULTI)
  164.                             DIAGS(("cmd_pipe: pid=%d, %s [=%d]\n",clnt_pid, op_code_names[parms->contrl[0]],parms->contrl[0]));
  165.                     }else
  166.                         DIAGS(("cmd_pipe: pid=%d, op-code=%d\n",clnt_pid, parms->contrl[0]));
  167. #endif
  168.  
  169. /* Call AES routine via jump table*/
  170.                     repl=XAC_DONE;
  171.                     if ((parms->contrl[0]>=0)&&(parms->contrl[0]<300))
  172.                     {
  173.                         cmd_routine=Ktable[parms->contrl[0]];
  174.                         if (cmd_routine!=NULL)        /* Do we support this op-code yet? */
  175.                         {
  176.                             repl=(*cmd_routine)(clnt_pid,parms);
  177.                             rtn=XA_OK;
  178.                         }else{
  179.                             DIAGS(("cmd_pipe: pid:%d, Opcode not implemented\n",clnt_pid));
  180.                             DIAGS(("          op-code=%d\n",parms->contrl[0]));
  181.                             rtn=XA_UNIMPLEMENTED;    /* Unimplemented functions :( */
  182.                         }
  183.                     }else{
  184.                         DIAGS(("XaAES: illegal AES opcode=%d\n",parms->contrl[0]));
  185.                         rtn=XA_ILLEGAL;                /* Illegal op-code - these may be caused by bugs in the client program */
  186.                     }
  187.         
  188. /* If client wants a reply, send it one - standard GEM programs will always do this, 
  189.    but XaAES aware programs don't always need to (depends if they are going to use the reply I suppose)
  190.    Some op-codes (evnt_multi for instance) will want to leave the client blocked until an event occurs.
  191.    I've added some extra blocking modes to support better timeouts..... */
  192.                     if ((cmd!=AESCMD_NOREPLY)&&(repl!=XAC_BLOCK))
  193.                     {
  194.                         r=repl&0xf;
  195.                         switch(r)
  196.                         {
  197.                             case XAC_T_TIMEOUT:
  198.                                 rtn=XA_T_WAIT|(repl&XAC_TVAL);
  199.                                 break;
  200.                             case XAC_M_TIMEOUT:
  201.                                 rtn=XA_M_WAIT|(repl&XAC_TVAL);
  202.                                 break;
  203.                             default:
  204.                                 break;
  205.                         }
  206.                         Fwrite(clients[clnt_pid].clnt_pipe_wr,sizeof(unsigned long),&rtn);
  207.                     }
  208.                 }
  209.             }
  210.         }
  211.         
  212.     }while(!shutdown);
  213. }
  214.  
  215. /*
  216.     Setup the AES kernal jump table
  217. */
  218.  
  219. void setup_k_function_table(void)
  220. {
  221.     short f;
  222.     for(f=0; f<300; f++)
  223.     {
  224.         Ktable[f]=NULL;
  225.         Kcall_direct[f]=FALSE;
  226.     }
  227.  
  228. /* appl_ class functions */
  229.     Ktable[XA_APPL_INIT]=&XA_appl_init;
  230.     Ktable[XA_APPL_EXIT]=&XA_appl_exit;
  231.     Ktable[XA_APPL_GETINFO]=&XA_appl_getinfo;
  232.     Ktable[XA_APPL_FIND]=&XA_appl_find;
  233.     Ktable[XA_APPL_WRITE]=&XA_appl_write;
  234.     Ktable[XA_APPL_SEARCH]=&XA_appl_search;
  235.     Kcall_direct[XA_APPL_INIT]=TRUE;        /* Must always call appl_init/exit directly */
  236.     Kcall_direct[XA_APPL_EXIT]=TRUE;
  237.     
  238. /* Form handlers (form_ xxxx) */
  239.     Ktable[XA_FORM_ALERT]=&XA_form_alert;
  240.     Ktable[XA_FORM_ERROR]=&XA_form_error;
  241.     Ktable[XA_FORM_CENTER]=&XA_form_center;
  242.     Ktable[XA_FORM_DIAL]=&XA_form_dial;
  243.     Ktable[XA_FORM_BUTTON]=&XA_form_button;
  244.     Ktable[XA_FORM_DO]=&XA_form_do;
  245.     Ktable[XA_FORM_KEYBD]=&XA_form_keybd;
  246.  
  247. /* File select (fsel_ xxx) */
  248.     Ktable[XA_FSEL_INPUT]=&XA_fsel_input;
  249.     Ktable[XA_FSEL_EXINPUT]=&XA_fsel_exinput;
  250.     Kcall_direct[XA_FSEL_INPUT]=TRUE;        /* Must always call fsel_xxx direct as they use a semaphore lock */
  251.     Kcall_direct[XA_FSEL_EXINPUT]=TRUE;
  252.  
  253. /* Event handlers (evnt_ xxx) */
  254.     Ktable[XA_EVNT_BUTTON]=&XA_evnt_button;
  255.     Ktable[XA_EVNT_KEYBD]=&XA_evnt_keybd;
  256.     Ktable[XA_EVNT_MESAG]=&XA_evnt_mesag;
  257.     Ktable[XA_EVNT_MULTI]=&XA_evnt_multi;
  258.     Ktable[XA_EVNT_TIMER]=&XA_evnt_timer;
  259.     CALL_DIRECT(XA_EVNT_BUTTON);
  260.     CALL_DIRECT(XA_EVNT_KEYBD);
  261.     CALL_DIRECT(XA_EVNT_TIMER);
  262.  
  263. /* graf_ class functions */
  264.     Ktable[XA_GRAF_RUBBERBOX]=&XA_graf_rubberbox;
  265.     Ktable[XA_GRAF_DRAGBOX]=&XA_graf_dragbox;
  266.     Ktable[XA_GRAF_HANDLE]=&XA_graf_handle;
  267.     Ktable[XA_GRAF_MOUSE]=&XA_graf_mouse;
  268.     Ktable[XA_GRAF_MKSTATE]=&XA_graf_mkstate;
  269.     Ktable[XA_GRAF_GROWBOX]=&XA_graf_growbox;
  270.     Ktable[XA_GRAF_SHRINKBOX]=&XA_graf_growbox;
  271.     Ktable[XA_GRAF_MOVEBOX]=&XA_graf_movebox;
  272.     Ktable[XA_GRAF_WATCHBOX]=&XA_graf_watchbox;
  273.     CALL_DIRECT(XA_GRAF_HANDLE);
  274.     CALL_DIRECT(XA_GRAF_MOUSE);
  275.     CALL_DIRECT(XA_GRAF_MKSTATE);
  276.     CALL_DIRECT(XA_GRAF_MOVEBOX);
  277.     CALL_DIRECT(XA_GRAF_GROWBOX);
  278.     CALL_DIRECT(XA_GRAF_SHRINKBOX);
  279.  
  280. /* Window Handling (wind_ xxxx) */
  281.     Ktable[XA_WIND_CREATE]=&XA_wind_create;
  282.     Ktable[XA_WIND_OPEN]=&XA_wind_open;
  283.     Ktable[XA_WIND_CLOSE]=&XA_wind_close;
  284.     Ktable[XA_WIND_SET]=&XA_wind_set;
  285.     Ktable[XA_WIND_GET]=&XA_wind_get;
  286.     Ktable[XA_WIND_FIND]=&XA_wind_find;
  287.     Ktable[XA_WIND_UPDATE]=&XA_wind_update;
  288.     Ktable[XA_WIND_DELETE]=&XA_wind_delete;
  289.     Ktable[XA_WIND_NEW]=&XA_wind_new;
  290.     Ktable[XA_WIND_CALC]=&XA_wind_calc;
  291.     CALL_DIRECT(XA_WIND_FIND);
  292.     CALL_DIRECT(XA_WIND_GET);        /* wind_get() is call direct to get a performance boost
  293.                                                                when redrawing */
  294.     Kcall_direct[XA_WIND_UPDATE]=TRUE;    /* wind_update must ALWAYS be call direct
  295.                                             as it uses semaphore locking */
  296.  
  297. /* Object Tree Handling (objc_ xxxx) */
  298.     Ktable[XA_OBJC_DRAW]=&XA_objc_draw;
  299.     Ktable[XA_OBJC_FIND]=&XA_objc_find;
  300.     Ktable[XA_OBJC_OFFSET]=&XA_objc_offset;
  301.     Ktable[XA_OBJC_CHANGE]=&XA_objc_change;
  302.     Ktable[XA_OBJC_EDIT]=&XA_objc_edit;
  303.     CALL_DIRECT(XA_OBJC_DRAW);
  304.     CALL_DIRECT(XA_OBJC_FIND);
  305.     CALL_DIRECT(XA_OBJC_OFFSET);
  306.     CALL_DIRECT(XA_OBJC_CHANGE);
  307.     
  308. /* Resource Handling */
  309.     Ktable[XA_RSRC_LOAD]=&XA_rsrc_load;
  310.     Ktable[XA_RSRC_FREE]=&XA_rsrc_free;
  311.     Ktable[XA_RSRC_GADDR]=&XA_rsrc_gaddr;
  312.     Ktable[XA_RSRC_OBFIX]=&XA_rsrc_obfix;
  313.     CALL_DIRECT(XA_RSRC_LOAD);
  314.     CALL_DIRECT(XA_RSRC_FREE);
  315.     CALL_DIRECT(XA_RSRC_GADDR);
  316.     CALL_DIRECT(XA_RSRC_OBFIX);
  317.  
  318. /* Menu Bar Handling */
  319.     Ktable[XA_MENU_BAR]=&XA_menu_bar;
  320.     Ktable[XA_MENU_TNORMAL]=&XA_menu_tnormal;
  321.     Ktable[XA_MENU_ICHECK]=&XA_menu_icheck;
  322.     Ktable[XA_MENU_IENABLE]=&XA_menu_ienable;
  323.     Ktable[XA_MENU_TEXT]=&XA_menu_text;
  324.     Ktable[XA_MENU_REGISTER]=&XA_menu_register;
  325.     CALL_DIRECT(XA_MENU_TNORMAL);
  326.     CALL_DIRECT(XA_MENU_ICHECK);
  327.     CALL_DIRECT(XA_MENU_IENABLE);
  328.  
  329. /* Shell  */
  330.     Ktable[XA_SHELL_WRITE]=&XA_shell_write;
  331.     Ktable[XA_SHELL_READ]=&XA_shell_read;
  332.     Ktable[XA_SHELL_FIND]=&XA_shell_find;
  333.     Ktable[XA_SHELL_ENVRN]=&XA_shell_envrn;
  334.  
  335. /* Scrap / Clipboard */
  336.     Ktable[XA_SCRAP_READ]=&XA_scrap_read;
  337.     Ktable[XA_SCRAP_WRITE]=&XA_scrap_write;
  338.  
  339. /* XaAES specific AES calls */
  340.     Ktable[XA_APPL_PIPE]=&XA_appl_pipe;
  341.  
  342. /*
  343.   XaAES kernal internal messages - applications should NEVER send these to the kernal,
  344.    they are used internally to pass crucial info from the client pid trap handler to 
  345.    the kernal.
  346. */
  347.     Ktable[XA_NEW_CLIENT]=&XA_new_client;
  348.     Ktable[XA_CLIENT_EXIT]=&XA_client_exit;
  349. }
  350.